package coin.yang.thread;

public class WaitNotifyDemo {

    public static void main(String[] args) {

        Product p = new Product();
        new Thread(new Producer(p)).start();
        new Thread(new Consumer(p)).start();

    }

}

// 生产者，生产商品
class Producer implements Runnable {

    private Product p;

    public Producer(Product p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (p) {
                // 生产者生产了商品之后，如果再次抢到执行权，暂停执行
                if (p.flag == false)
                    try {
                        p.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                // 计算本次生产的商品数量(100~1000)
                int count = (int) (Math.random() * 900 + 100);
                p.setCount(count);
                System.out.println("生产者本次生产了：" + count + "件商品");
                // 生产者生产完商品之后，唤醒消费者，该消费者起来消费了
                p.flag = false;
                p.notify();
            }
        }
    }

}

class Consumer implements Runnable {

    private Product p;

    public Consumer(Product p) {
        this.p = p;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (p) {
                // 消费者消费一次之后，如果再次抢到执行权，应该也需要等一会儿
                if (p.flag == true)
                    try {
                        p.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                // 消费者获取商品数量
                int count = p.getCount();
                p.setCount(0);
                System.out.println("消费者本次消费了" + count + "件商品");
                // 消费者消费完之后，需要通知生产者该生产了，不能继续等着了
                p.flag = true;
                p.notify();
            }
        }
    }
}

// 消费者，消费商品

// 定义一个类表示商品
class Product {
    private int count;
    // true标记需要生产者执行，false标记消费者执行
    public boolean flag = true;

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}
